package com.ai.service.made.impl;

import com.ai.common.CommonResponse;
import com.ai.common.constant.enumP.QuestionType;
import com.ai.entity.BasePage;
import com.ai.entity.exam.*;
import com.ai.entity.security.SysUser;
import com.ai.mapper.made.MirrorExamMapper;
import com.ai.service.made.*;
import com.ai.service.security.ISysUserService;
import com.ai.util.SecurityUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.View;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 试卷(MirrorExam)表服务实现类
 *
 * @author makejava
 * @since 2024-07-01 18:06:24
 */
@Service
@Slf4j
public class MirrorExamServiceImpl extends ServiceImpl<MirrorExamMapper, MirrorExam> implements MirrorExamService {


    @Resource
    MirrorExamQuestionsService mirrorExamQuestionsService;

    @Resource
    MirrorExamOptionService mirrorExamOptionService;

    @Resource
    ExamRecordService examRecordService;

    @Resource
    ExamRecordAnswerInfoService examRecordAnswerInfoService;

    @Resource
    ExamRecordInfoService examRecordInfoService;

    @Autowired
    ISysUserService iSysUserService;


    /**
     * 根据镜像考试ID获取考试详情。
     *
     * @param mirrorExam 代表镜像考试的对象
     * @return 返回考试的详细信息，如果不存在或未启用，则返回错误信息。
     */
    @Override
    public CommonResponse select(MirrorExam mirrorExam) {
        // 获取镜像考试的ID
        Integer mirrorExamId = mirrorExam.getId();

        // 检查镜像考试ID是否为空
        if (mirrorExamId == null) {
            return CommonResponse.error("试卷Id为空");
        }

        // 根据ID查询镜像考试信息
        MirrorExam examById = this.getById(mirrorExamId);
        // 检查考试是否存在并是否启用
        if (examById == null || "0".equals(examById.getIsAvailable())) {
            return CommonResponse.error("该试卷未启用");
        }

        // 初始化题目详情映射
        Map<QuestionType, List<QuestionDetails>> questionDetailsMap = new HashMap<>();
        // 根据考试ID查询题目列表
        List<MirrorExamQuestions> mirrorExamQuestionsList = mirrorExamQuestionsService.selectByExamId(mirrorExamId);

        // 遍历题目列表，构建题目详情
        for (MirrorExamQuestions questions : mirrorExamQuestionsList) {
            // 检查题目ID是否为空
            if (questions.getId() == null) {
                return CommonResponse.error("题目id为空");
            }

            // 将题目类型转换为枚举类型
            // 假设有一个方法将字符串转换为枚举
            QuestionType type = QuestionType.value(questions.getType());
            // 检查题目类型是否有效
            if (type == null) {
                return CommonResponse.error("题目类型错误");
            }

            // 创建题目详情对象并添加到相应的类型列表中
            QuestionDetails questionDetails = createQuestionDetails(questions, type);
            //通过computeIfAbsent方法根据type获取Map中对应的List，
            // 如果Map中不存在该type对应的List，则使用lambda表达式k -> new ArrayList<>()创建一个新的ArrayList；
            questionDetailsMap.computeIfAbsent(type, k -> new ArrayList<>()).add(questionDetails);
        }

        // 构建考试VO对象，包含各个题目的详细信息
        List<ExamVO.examQuestionVO> subjectList = new ArrayList<>();
        questionDetailsMap.forEach((type, list) -> {
            ExamVO.examQuestionVO examQuestionVO = new ExamVO.examQuestionVO();
            examQuestionVO.setType(type.getCode());
            examQuestionVO.setQuestionList(list);
            subjectList.add(examQuestionVO);
        });

        ExamVO examVO = new ExamVO();
        examVO.setSubjectList(subjectList);
        examVO.setId(mirrorExamId);
        examVO.setExamTitle(examById.getExamTitle());

        // 返回构建完成的考试详情VO
        return CommonResponse.ok(examVO);
    }


    /**
     * 根据题目和类型创建题目详情对象。
     *
     * @param questions 考试题目信息
     * @param type      题目类型
     * @return 返回题目详情对象
     */
    private QuestionDetails createQuestionDetails(MirrorExamQuestions questions, QuestionType type) {
        QuestionDetails questionDetails = new QuestionDetails();
        questionDetails.setQuestionsId(questions.getId());
        questionDetails.setQuestion(questions.getQuestion());
        questionDetails.setMarks(questions.getMarks());

        // 如果题目类型不是判断题，则查询选项信息
        if (type != QuestionType.JUDGEMENT) {
            List<MirrorExamOption> optionList = mirrorExamOptionService.selectByQuestionsId(questions.getId());
            List<QuestionDetails.option> options = new ArrayList<>();
            for (MirrorExamOption mirrorExamOption : optionList) {
                QuestionDetails.option option = new QuestionDetails.option();
                option.setContent(mirrorExamOption.getOptionContent());
                option.setOptionId(mirrorExamOption.getId());
                options.add(option);
            }
            questionDetails.setOptionList(options);
        }
        return questionDetails;
    }


    /**
     * 获取考试得分详情
     *
     * @param answerBO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResponse getScoreDetail(AnswerBO answerBO) {


        List<AnswerBO.answer> answerList = answerBO.getAnswerList();

        int marks = 0;

        List<ExamRecordInfoPO> examRecordInfoPOList = new ArrayList<>();

        List<ExamRecordAnswerInfoPO> examRecordAnswerInfoPOList = new ArrayList<>();

        List<Integer> correctQuestionId = new ArrayList<>();

        List<Integer> errorQuestionId = new ArrayList<>();

        for (AnswerBO.answer answer : answerList) {
            if (Objects.equals(QuestionType.value(answer.getType()), QuestionType.SINGLE_CHOICE)) {
                //表示单选
                List<AnswerBO.answer.answerDetails> answerDetailsList = answer.getAnswerDetails();
                for (AnswerBO.answer.answerDetails answerDetails : answerDetailsList) {
                    //获取题目id
                    Integer questionsId = answerDetails.getQuestionsId();
                    ExamRecordInfoPO examRecordInfoPO = new ExamRecordInfoPO();
                    ExamRecordAnswerInfoPO examRecordAnswerInfoPO = new ExamRecordAnswerInfoPO();
                    examRecordInfoPO.setExamQuestionId(questionsId);
                    List<Integer> respondAnswer = answerDetails.getRespondAnswer();
                    if (respondAnswer.size() == 1) {
                        //获取用户选择答案的选项Id
                        Integer userAnswer = respondAnswer.get(0);
                        examRecordAnswerInfoPO.setSelectedId(userAnswer);
                        examRecordAnswerInfoPOList.add(examRecordAnswerInfoPO);
                        QueryWrapper<MirrorExamOption> queryWrapper = new QueryWrapper<>();

                        queryWrapper.eq("question_id", questionsId)
                                .eq("is_correct", "1");

                        MirrorExamOption mirrorExamOption = mirrorExamOptionService.getOne(queryWrapper);

                        if (mirrorExamOption == null) {
                            return CommonResponse.error("该题目不存在");
                        }


                        if (userAnswer.equals(mirrorExamOption.getId())) {
                            //表示答对
                            MirrorExamQuestions mirrorExamQuestionsServiceById = mirrorExamQuestionsService.getById(questionsId);

                            marks = marks + Integer.parseInt(mirrorExamQuestionsServiceById.getMarks());
                            correctQuestionId.add(questionsId);


                            examRecordInfoPO.setAnswerSituation("1");

                            examRecordInfoPOList.add(examRecordInfoPO);
                            ;
                        } else {
                            errorQuestionId.add(questionsId);

                            examRecordInfoPO.setAnswerSituation("2");

                            examRecordInfoPOList.add(examRecordInfoPO);
                        }
                    } else {
                        return CommonResponse.error("单选题不能选多个答案");
                    }
                }
            } else if (Objects.equals(QuestionType.value(answer.getType()), QuestionType.MULTIPLE_CHOICE)) {
                //表示多选
                List<AnswerBO.answer.answerDetails> answerDetailsList = answer.getAnswerDetails();
                for (AnswerBO.answer.answerDetails answerDetails : answerDetailsList) {
                    //获取题目id
                    Integer questionsId = answerDetails.getQuestionsId();
                    List<Integer> respondAnswer = answerDetails.getRespondAnswer();
                    ExamRecordInfoPO examRecordInfoPO = new ExamRecordInfoPO();
                    examRecordInfoPO.setExamQuestionId(questionsId);
                    ExamRecordAnswerInfoPO examRecordAnswerInfoPO = new ExamRecordAnswerInfoPO();


                    for (Integer integer : respondAnswer) {
                        examRecordAnswerInfoPO.setSelectedId(integer);
                        examRecordAnswerInfoPOList.add(examRecordAnswerInfoPO);
                    }

                    QueryWrapper<MirrorExamOption> queryWrapper = new QueryWrapper<>();

                    queryWrapper.eq("question_id", questionsId)
                            .eq("is_correct", "1");
                    List<Integer> list = mirrorExamOptionService.list(queryWrapper).stream()
                            .map(MirrorExamOption::getId)
                            .collect(Collectors.toList());

                    Set<Integer> set1 = new HashSet<>(respondAnswer);
                    Set<Integer> set2 = new HashSet<>(list);

                    if (set1.equals(set2)) {
                        //表示答对
                        MirrorExamQuestions mirrorExamQuestionsServiceById = mirrorExamQuestionsService.getById(questionsId);

                        marks = marks + Integer.parseInt(mirrorExamQuestionsServiceById.getMarks());
                        correctQuestionId.add(questionsId);

                        examRecordInfoPO.setAnswerSituation("1");

                        examRecordInfoPOList.add(examRecordInfoPO);

                    } else {
                        errorQuestionId.add(questionsId);

                        examRecordInfoPO.setAnswerSituation("2");

                        examRecordInfoPOList.add(examRecordInfoPO);
                    }


                }
            } else if (Objects.equals(QuestionType.value(answer.getType()), QuestionType.JUDGEMENT)) {
                //表示判断
                List<AnswerBO.answer.answerDetails> answerDetailsList = answer.getAnswerDetails();


                for (AnswerBO.answer.answerDetails answerDetails : answerDetailsList) {
                    //获取题目id
                    Integer questionsId = answerDetails.getQuestionsId();
                    ExamRecordInfoPO examRecordInfoPO = new ExamRecordInfoPO();
                    examRecordInfoPO.setExamQuestionId(questionsId);
                    //获取用户所选的答案
                    String correctAnswer = answerDetails.getJudgementAnswer();

                    ExamRecordAnswerInfoPO examRecordAnswerInfoPO = new ExamRecordAnswerInfoPO();

                    if ("1".equals(correctAnswer)) {
                        //表示该考生这个判断题选择正确选项
                        examRecordAnswerInfoPO.setSelectedId(-1);

                    } else if ("0".equals(correctAnswer)) {
                        examRecordAnswerInfoPO.setSelectedId(-2);
                    } else {
                        return CommonResponse.error("判断题只能选择正确或错误");
                    }

                    examRecordAnswerInfoPOList.add(examRecordAnswerInfoPO);

                    MirrorExamQuestions mirrorExamQuestionsServiceById = mirrorExamQuestionsService.getById(questionsId);

                    if (Objects.equals(correctAnswer, mirrorExamQuestionsServiceById.getCorrectAnswer())) {
                        //表示答对
                        marks = marks + Integer.parseInt(mirrorExamQuestionsServiceById.getMarks());
                        correctQuestionId.add(questionsId);
                        examRecordInfoPO.setAnswerSituation("1");
                        examRecordInfoPOList.add(examRecordInfoPO);
                    } else {
                        errorQuestionId.add(questionsId);
                        examRecordInfoPO.setAnswerSituation("2");
                        examRecordInfoPOList.add(examRecordInfoPO);
                    }
                }
            }
        }

        ExamRecordVO examRecordVO = new ExamRecordVO();

        examRecordVO.setMark(String.valueOf(marks));
        examRecordVO.setCreateTime(new Date());
        examRecordVO.setUpdateTime(new Date());
        if (marks >= 60) {
            examRecordVO.setExamResult("1");
        } else {
            examRecordVO.setExamResult("2");
        }

        String loginUserName = SecurityUtils.getLoginUserName();

        SysUser sysUser = iSysUserService.selectByName(loginUserName);

        examRecordVO.setAccount(sysUser.getAccount());
        examRecordVO.setUserName(sysUser.getUserName());
        examRecordVO.setDepartment(sysUser.getDepartment());
        examRecordVO.setCorrectQuestionId(correctQuestionId);
        examRecordVO.setErrorQuestionId(errorQuestionId);
        examRecordVO.setExamType("1");
        //保存考试记录
        ExamRecordPO examRecordPO = new ExamRecordPO();


        examRecordPO.setUserId(sysUser.getId());
        examRecordPO.setMark(String.valueOf(marks));
        examRecordPO.setUpdateUser(sysUser.getUserName());
        examRecordPO.setCreateUser(sysUser.getUserName());
        examRecordPO.setExamResult(examRecordVO.getExamResult());
        examRecordPO.setExamType(examRecordVO.getExamType());
        try {
            examRecordService.insert(examRecordPO);
            Integer recordPOId = examRecordPO.getId();
            if (recordPOId == null) {
                //表示插入失败
                return CommonResponse.error("考试记录保存失败");
            }
            examRecordVO.setId(recordPOId);
            //开始插入考试考生题目表
            for (ExamRecordInfoPO examRecordInfoPO : examRecordInfoPOList) {

                examRecordInfoPO.setExamRecordId(recordPOId);

                examRecordInfoPO.setCreateUser(sysUser.getUserName());
                examRecordInfoPO.setUpdateUser(sysUser.getUserName());
                examRecordInfoService.insert(examRecordInfoPO);

                Integer examRecordInfoPOId = examRecordInfoPO.getId();

                if (examRecordInfoPOId == null) {
                    return CommonResponse.error("考试考生题目保存失败");
                }

                for (AnswerBO.answer answer : answerList) {
                    List<AnswerBO.answer.answerDetails> answerDetailsList = answer.getAnswerDetails();

                    for (AnswerBO.answer.answerDetails answerDetails : answerDetailsList) {
                        Integer questionsId = answerDetails.getQuestionsId();

                        if (Objects.equals(questionsId, examRecordInfoPO.getExamQuestionId())) {
                            if (Objects.equals(QuestionType.value(answer.getType()), QuestionType.SINGLE_CHOICE) || Objects.equals(QuestionType.value(answer.getType()), QuestionType.MULTIPLE_CHOICE)) {
                                List<Integer> respondAnswer = answerDetails.getRespondAnswer();

                                for (Integer integer : respondAnswer) {
                                    ExamRecordAnswerInfoPO examRecordAnswerInfoPO = new ExamRecordAnswerInfoPO();
                                    examRecordAnswerInfoPO.setExamRecordInfoId(examRecordInfoPOId);
                                    examRecordAnswerInfoPO.setSelectedId(integer);
                                    examRecordAnswerInfoPO.setCreateUser(sysUser.getUserName());
                                    examRecordAnswerInfoPO.setUpdateUser(sysUser.getUserName());
                                    examRecordAnswerInfoService.insert(examRecordAnswerInfoPO);
                                }

                            } else {
                                ExamRecordAnswerInfoPO examRecordAnswerInfoPO = new ExamRecordAnswerInfoPO();
                                examRecordAnswerInfoPO.setExamRecordInfoId(examRecordInfoPOId);
                                String judgementAnswer = answerDetails.getJudgementAnswer();
                                if ("0".equals(judgementAnswer)) {
                                    examRecordAnswerInfoPO.setSelectedId(-1);
                                } else if ("1".equals(judgementAnswer)) {
                                    examRecordAnswerInfoPO.setSelectedId(-2);
                                } else {
                                    return CommonResponse.error("选项有误");

                                }
                                examRecordAnswerInfoPO.setCreateUser(sysUser.getUserName());
                                examRecordAnswerInfoPO.setUpdateUser(sysUser.getUserName());
                                examRecordAnswerInfoService.insert(examRecordAnswerInfoPO);
                            }
                        }
                    }
                }
            }
        } catch (
                Exception e) {
            log.info("考生考试记录保存失败,{}", e.getMessage());
            return CommonResponse.error("考试记录保存失败");
        }

        return CommonResponse.ok(examRecordVO);
    }

    @Override
    public CommonResponse getExamRecordPage(ExamRecordPage examRecordPage) {

        IPage<ExamRecordVO> iPage = new BasePage<>();

        QueryWrapper<ExamRecordPO> queryWrapper = new QueryWrapper<>();

        queryWrapper.orderByDesc("er.create_time");

        queryWrapper = examRecordPage.getQuery(queryWrapper);

        iPage = examRecordService.selectPage(examRecordPage, queryWrapper);

        return CommonResponse.ok(iPage);
    }


    /**
     * 通过考试信息Id查询考试详细信息
     *
     * @param examRecordId
     * @return
     */
    @Override
    public CommonResponse getExamRecordById(Integer examRecordId) {

        if (examRecordId == null) {
            return CommonResponse.error("考试信息Id不能为空");
        }
        // 初始化题目详情映射
        Map<QuestionType, List<QuestionDetails>> questionDetailsMap = new HashMap<>();

        List<ExamRecordInfoPO> examRecordInfoList = examRecordInfoService.selectByExamRecordId(examRecordId);

        for (ExamRecordInfoPO examRecordInfoPO : examRecordInfoList) {
            //获取题目Id
            Integer examQuestionId = examRecordInfoPO.getExamQuestionId();

            //根据题目ID查看相关题目信息
            MirrorExamQuestions mirrorExamQuestions = mirrorExamQuestionsService.selectById(examQuestionId);

            // 假设有一个方法将字符串转换为枚举
            QuestionType type = QuestionType.value(mirrorExamQuestions.getType());


            QuestionDetails questionDetails = (QuestionDetails) getQuestionDetails(examQuestionId, examRecordInfoPO.getId(), mirrorExamQuestions, type).getData();


            //通过computeIfAbsent方法根据type获取Map中对应的List，
            // 如果Map中不存在该type对应的List，则使用lambda表达式k -> new ArrayList<>()创建一个新的ArrayList；
            questionDetailsMap.computeIfAbsent(type, k -> new ArrayList<>()).add(questionDetails);
        }

        // 构建考试VO对象，包含各个题目的详细信息
        List<ExamVO.examQuestionVO> subjectList = new ArrayList<>();
        questionDetailsMap.forEach((type, list) -> {
            ExamVO.examQuestionVO examQuestionVO = new ExamVO.examQuestionVO();
            examQuestionVO.setType(type.getCode());
            examQuestionVO.setQuestionList(list);
            subjectList.add(examQuestionVO);
        });

        ExamVO examVO = new ExamVO();
        examVO.setSubjectList(subjectList);

        // 返回构建完成的考试详情VO
        return CommonResponse.ok(examVO);
    }


    public CommonResponse getQuestionDetails(Integer questionId, Integer examRecordId, MirrorExamQuestions mirrorExamQuestions, QuestionType type) {
        List<Integer> correntAnswerIdList = new ArrayList<>();

        List<Integer> respondAnswerList = new ArrayList<>();

        // 检查题目类型是否有效
        if (type == null) {
            return CommonResponse.error("题目类型错误");
        }

        // 创建题目详情对象并添加到相应的类型列表中
        QuestionDetails questionDetails = createQuestionDetails(mirrorExamQuestions, type);

        List<ExamRecordAnswerInfoPO> examRecordAnswerInfoPOList = examRecordAnswerInfoService.selectByExamRecordInfoId(examRecordId);

        if (type == QuestionType.SINGLE_CHOICE) {
            //根据题目Id该题目正确答案
            QueryWrapper<MirrorExamOption> queryWrapper = new QueryWrapper<>();

            queryWrapper.eq("question_id", questionId)
                    .eq("is_correct", "1");

            MirrorExamOption mirrorExamOption = mirrorExamOptionService.getOne(queryWrapper);

            correntAnswerIdList.add(mirrorExamOption.getId());

            //根据题目id查询考试信息表id

            Integer selectedId = examRecordAnswerInfoPOList.get(0).getSelectedId();

            respondAnswerList.add(selectedId);

        } else if (type == QuestionType.MULTIPLE_CHOICE) {

            QueryWrapper<MirrorExamOption> queryWrapper = new QueryWrapper<>();

            queryWrapper.eq("question_id", questionId)
                    .eq("is_correct", "1");
            List<Integer> list = mirrorExamOptionService.list(queryWrapper).stream()
                    .map(MirrorExamOption::getId)
                    .collect(Collectors.toList());

            correntAnswerIdList.addAll(list);

            //根据题目id查询考试信息表id

            respondAnswerList.addAll(examRecordAnswerInfoPOList.stream()
                    .map(ExamRecordAnswerInfoPO::getSelectedId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList()));
        } else if (type == QuestionType.JUDGEMENT) {

            String correctAnswer = mirrorExamQuestions.getCorrectAnswer();

            correntAnswerIdList.add(Integer.valueOf(correctAnswer));

            ExamRecordAnswerInfoPO examRecordAnswerInfoPO = examRecordAnswerInfoPOList.get(0);

            if (examRecordAnswerInfoPO.getSelectedId().equals(-1)) {
                //表示考生所选答案为正确该选项
                respondAnswerList.add(1);
            } else if (examRecordAnswerInfoPO.getSelectedId().equals(-2)) {
                respondAnswerList.add(0);
            } else {
                return CommonResponse.error("考生答案错误");
            }

        } else {
            return CommonResponse.error("题目类型错误");
        }

        questionDetails.setCorrentAnswerId(correntAnswerIdList);
        questionDetails.setRespondAnswerId(respondAnswerList);

        return CommonResponse.ok(questionDetails);
    }


    /**
     * 根据题目Id查询题目相关信息
     *
     * @param questionId
     * @return
     */
    @Override
    public CommonResponse getQuestionDetailsByQuestionId(Integer questionId, Integer examRecordId) {

        if (questionId == null) {
            return CommonResponse.error("题目Id不能为空");
        }

        if (examRecordId == null){
            return CommonResponse.error("考试记录Id不能为空");
        }

        //根据题目Id查询题目相关信息
        MirrorExamQuestions mirrorExamQuestions = mirrorExamQuestionsService.selectById(questionId);


        //根据题目Id查询选项信息
        List<MirrorExamOption> mirrorExamOptionList = mirrorExamOptionService.selectByQuestionsId(questionId);

        List<QuestionDetails.option> optionList = new ArrayList<>();

        for (MirrorExamOption mirrorExamOption : mirrorExamOptionList) {
            QuestionDetails.option option = new QuestionDetails.option();
            option.setOptionId(mirrorExamOption.getId());
            option.setContent(mirrorExamOption.getOptionContent());
            optionList.add(option);
        }


        // 假设有一个方法将字符串转换为枚举
        QuestionType type = QuestionType.value(mirrorExamQuestions.getType());

        //根据考试id和题目Id得到考试信息题目表ID
        QueryWrapper<ExamRecordInfoPO>queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("exam_question_id",questionId)
                .eq("exam_record_id",examRecordId);

        ExamRecordInfoPO examRecordInfoPO = examRecordInfoService.getOne(queryWrapper);

        QuestionDetails questionDetails = (QuestionDetails) getQuestionDetails(questionId, examRecordInfoPO.getId(), mirrorExamQuestions, type).getData();


        questionDetails.setOptionList(optionList);
        questionDetails.setMarks(mirrorExamQuestions.getMarks());
        questionDetails.setQuestionsId(mirrorExamQuestions.getId());
        questionDetails.setQuestion(mirrorExamQuestions.getQuestion());

        return CommonResponse.ok(questionDetails);
    }
}
